package com.zh.onlineexam.config;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zh.onlineexam.common.OperaLog;
import com.zh.onlineexam.entity.TUserEventLog;
import com.zh.onlineexam.entity.TUserToken;
import com.zh.onlineexam.entity.User;
import com.zh.onlineexam.service.TUserEventLogService;
import com.zh.onlineexam.service.TUserTokenService;
import com.zh.onlineexam.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * 2022-08-07记录用户表的最新活跃时间 lastActiveTime
 * */
@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
public class LogAspect {
    private final UserService userService;
    private final TUserEventLogService tUserEventLogService;
    private final TUserTokenService tUserTokenService;
    /**
     * 设置操作日志切入点 记录操作日志 在注解的位置切入代码
     */
    @Pointcut("@annotation(com.zh.onlineexam.common.OperaLog)")
    public void pointCut() {
    }
    @Pointcut("execution(* com.zh.onlineexam.controller.UserController.deleteUser(..))")
    public void deleteUserPoinCut() {
    }

    /**
     * 正常返回通知，拦截用户操作日志，连接点正常执行完成后执行， 如果连接点抛出异常，则不会执行
     *
     * @param joinPoint 切入点
     */
    @AfterReturning(value = "pointCut()")
    public void saveOperLog(JoinPoint joinPoint){
        if(!ObjectUtil.isEmpty(StpUtil.getTokenValue())){
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                // 从切面织入点处通过反射机制获取织入点处的方法
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                // 获取切入点所在的方法User.getId()
                Method method = signature.getMethod();
                // 获取操作
                OperaLog opLog = method.getAnnotation(OperaLog.class);
                //object对象转成对应实体类
                //User user = new ObjectMapper().convertValue(arg, User.class);
                //QueryWrapper<User> wepper = new QueryWrapper<>();
                //if(StrUtil.isNotBlank(user.getUserName())){
                //    wepper.eq("user_name",user.getUserName());
                //}
                //if(StrUtil.isNotBlank(user.getRealName())){
                //    wepper.like("real_name",user.getRealName());
                //}
                Object loginId = StpUtil.getLoginId();
                User one = userService.getOne(new QueryWrapper<User>().eq("id", loginId));
                //User one = userService.getOne(wepper);
                //同步TUserEventLog
                TUserEventLog tUserEventLog = new TUserEventLog();
                tUserEventLog.setUserId(one.getId());
                tUserEventLog.setUserName(one.getUserName());
                tUserEventLog.setRealName(one.getRealName());
                tUserEventLog.setContent(opLog.operaType());
                tUserEventLog.setCreateTime(new Date());
                tUserEventLogService.save(tUserEventLog);
                //同步TUserToken
                TUserToken tUserToken = new TUserToken();
                tUserToken.setToken(StpUtil.getTokenValue());
                tUserToken.setUserId(one.getId());
                tUserToken.setWxOpenId("");
                tUserToken.setUserName(one.getUserName());
                tUserTokenService.save(tUserToken);
            }
        }
    }
    @Before(value = "deleteUserPoinCut()")
    public void operDeleteUserPoinCut(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            //object对象转成对应实体类
            User user = new ObjectMapper().convertValue(arg, User.class);
            User one = userService.getOne(new QueryWrapper<User>().eq("id",user.getId() ).last(" limit 1"));
            //同步TUserEventLog
            TUserEventLog tUserEventLog = new TUserEventLog();
            tUserEventLog.setUserId(one.getId());
            tUserEventLog.setUserName(one.getUserName());
            tUserEventLog.setRealName(one.getRealName());
            tUserEventLog.setContent("删除用户");
            tUserEventLog.setCreateTime(new Date());
            tUserEventLogService.save(tUserEventLog);
        }
    }
}
